<template>
    <div class="menu-management">
        <!-- 标题区域 -->
        <div class="box">
            <div class="size-24">角色管理</div>
        </div>

        <!-- 搜索区域 -->
        <div class="search-bar">
            <div class="search-group flex gap-4 items-center">
                <el-input v-model="searchName" clearable style="width: 250px" placeholder="请输入角色名称"
                    :suffix-icon="Search" @change="handleSearch" />
            </div>
            <!-- 新增按钮 -->
            <el-button type="primary" @click="openAddForm">新增</el-button>
        </div>
        <!-- 表单 -->
        <el-table :data="tableData" style="width: 100%" border stripe>
            <el-table-column label="序号" width="80" align="center">
                <template #default="scope">
                    {{ (currentPage4 - 1) * pageSize4 + scope.$index + 1 }}
                </template>
            </el-table-column>
            <el-table-column property="name" label="角色名称" width="130" align="center" />
            <el-table-column label="角色类型" width="180" align="center">
                <template #default="scope">
                    <el-tag type="primary">
                        {{
                            scope.row.type === 1
                                ? '超级管理员'
                                : scope.row.type === 2
                                    ? '劳务公司'
                                    : scope.row.type === 3
                                        ? '项目部'
                                        : '审核员'
                        }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="可访问菜单" width="700" align="center" show-overflow-tooltip>
                <template #default="scope">
                    {{ scope.row.menus_name?.join(',') || '无' }} <!-- 处理menus_name为undefined的情况 -->
                </template>
            </el-table-column>
            <el-table-column label="操作" align="center">
                <template #default="scope">
                    <!-- 编辑按钮：点击传递当前行数据 -->
                    <el-button type="primary" size="small" @click="openEditForm(scope.row)">编辑</el-button>
                    <el-button type="danger" size="small" @click="open(scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <!-- 分页：已与分页参数绑定-->
        <div class="demo-pagination-block">
            <el-pagination v-model:current-page="currentPage4" v-model:page-size="pageSize4"
                :page-sizes="[5, 10, 20, 100]" :size="size" :background="background"
                layout="total, sizes, prev, pager, next, jumper" :total="pagetotle" @size-change="handleSizeChange"
                @current-change="handleCurrentChange" />
        </div>

        <!-- 新增/编辑表单弹窗：默认隐藏，点击“新增”或“编辑”按钮显示 -->
        <el-dialog :title="isEditMode ? '编辑角色' : '新增角色'" v-model="isFormShow" width="600px" @close="closeForm">
            <el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px">
                <!-- 角色名称 -->
                <el-form-item label="角色名称" prop="name">
                    <el-input v-model="formData.name" placeholder="请输入角色名称" style="width: 100%;" />
                </el-form-item>
                <!-- 角色类型 -->
                <el-form-item label="角色类型" prop="type">
                    <el-select v-model="formData.type" placeholder="请选择角色类型" style="width: 100%;">
                        <el-option label="超级管理员" value="1" />
                        <el-option label="劳务公司" value="2" />
                        <el-option label="项目部" value="3" />
                        <el-option label="审核员" value="4" />
                    </el-select>
                </el-form-item>
                <!-- 可访问菜单：绑定el-tree实例，用于回显选中状态 -->
                <el-form-item label="可访问菜单" prop="valueMenu">
                    <el-tree ref="menuTreeRef" :data="treeMenuData" :render-after-expand="false" style="width: 240px"
                        show-checkbox node-key="value" @check-change="handleCheckChange" />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="closeForm">取消</el-button>
                <el-button type="primary" @click="submitForm">确认</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted, reactive, nextTick } from 'vue';
import { Search } from '@element-plus/icons-vue';
import { ElMessage, ComponentSize, ElMessageBox, ElTree } from 'element-plus';
import type { FormInstance, FormRules } from 'element-plus';

// 引入接口（假设roleList返回角色列表，其中包含角色的menus字段（菜单ID字符串））
import { roleList, roleDelete, roleAdd } from '/@/api/permissions/role';
import { menuList } from '/@/api/permissions/menus';

// ---------------------- 表格与分页相关 ----------------------
const currentPage4 = ref(1);    // 当前页码
const pageSize4 = ref(10);       // 每页条数
const size = ref<ComponentSize>('default'); // 分页组件尺寸
const background = ref(true);   // 分页组件背景
const searchName = ref('');     // 搜索关键字
const fullTableData = ref<any[]>([]); // 存储后端返回的全部原始数据
const tableData = ref<any[]>([]);     // 存储分页后的数据（表格实际渲染）
const pagetotle = ref(0);             // 总数据条数

// ---------------------- 树形菜单相关 ----------------------
const menuTreeRef = ref<InstanceType<typeof ElTree> | null>(null); // el-tree实例，用于回显选中
const treeMenuData = ref<any[]>([]); // 处理后的树形菜单数据
const valueMenu = ref<string[] | number[]>([]); // 存储选中的菜单ID（用于提交）

// 组件挂载后加载初始数据
onMounted(() => {
    fetchFullData();
    fetchAndProcessMenuData();
});

// 1. 获取角色列表（带搜索）
const fetchFullData = async (searchKey = '') => {
    try {
        const res = await roleList({ name: searchKey }); // 传搜索参数
        fullTableData.value = res.data || []; // 存完整数据（假设每条角色数据含id/name/type/menus（菜单ID字符串）/menus_name）
        pagetotle.value = fullTableData.value.length; // 同步总条数
        getPaginatedData(); // 生成当前页数据
    } catch (err) {
        console.error('获取角色数据失败', err);
        ElMessage.error('获取角色数据失败，请重试');
        fullTableData.value = [];
        tableData.value = [];
        pagetotle.value = 0;
    }
};

// 2. 分页计算
const getPaginatedData = () => {
    const startIndex = (currentPage4.value - 1) * pageSize4.value;
    const endIndex = startIndex + pageSize4.value;
    tableData.value = fullTableData.value.slice(startIndex, endIndex);
};

// 3. 搜索/分页切换事件
const handleSearch = () => {
    currentPage4.value = 1;
    fetchFullData(searchName.value);
};
const handleSizeChange = (val: number) => {
    pageSize4.value = val;
    currentPage4.value = 1;
    getPaginatedData();
};
const handleCurrentChange = (val: number) => {
    currentPage4.value = val;
    getPaginatedData();
};

// 4. 构建树形菜单数据
const buildTreeMenu = (menus: any[], parentId: number): any[] => {
    return menus
        .filter(menu => menu.pid === parentId)
        .map(menu => {
            const treeNode = {
                value: menu.id, // 菜单ID（与角色的menus字段对应）
                label: menu.title, // 菜单名称
                children: [] as any[]
            };
            const children = buildTreeMenu(menus, menu.id);
            if (children.length > 0) treeNode.children = children;
            return treeNode;
        });
};

// 5. 获取菜单数据（用于树形渲染）
const fetchAndProcessMenuData = async () => {
    try {
        const res = await menuList({ title: '' });
        const rawMenus = res.data || [];
        treeMenuData.value = buildTreeMenu(rawMenus, 0); // 顶级菜单parentId=0
    } catch (err) {
        console.error('获取菜单数据失败', err);
        ElMessage.error('获取菜单数据失败，请重试');
        treeMenuData.value = [];
    }
};

// ---------------------- 新增/编辑表单相关 ----------------------
const isFormShow = ref(false); // 弹窗显示状态
const isEditMode = ref(false); // 编辑模式标识
const currentEditId = ref<any>(); // 当前编辑的角色ID
const formRef = ref<FormInstance | null>(null); // 表单实例

// 表单数据
const formData = reactive({
    name: '',       // 角色名称
    type: '',       // 角色类型（1-4）
    valueMenu: [],   // 选中的菜单ID（用于表单验证）
});

// 表单验证规则（新增菜单必选校验）
const formRules = reactive<FormRules<typeof formData>>({
    name: [
        { required: true, message: '请输入角色名称', trigger: 'blur' }
    ],
    type: [
        { required: true, message: '请选择角色类型', trigger: 'blur' }
    ],
    valueMenu: [
        { required: true, message: '请选择可访问菜单', trigger: 'change' }
    ]
});

// 6. 树形菜单选中变化：同步到formData.valueMenu（用于表单验证）
const handleCheckChange = () => {
    if (!menuTreeRef.value) return;
    // 获取所有选中的菜单ID（包括子节点）
    const checkedKeys = menuTreeRef.value.getCheckedKeys();
    formData.valueMenu = checkedKeys;
    valueMenu.value = checkedKeys; // 同步到提交用的valueMenu
};

// 7. 打开新增弹窗
const openAddForm = () => {
    isEditMode.value = false;
    currentEditId.value = null;
    // 重置表单和树形菜单
    if (formRef.value) formRef.value.resetFields();
    if (menuTreeRef.value) menuTreeRef.value.setCheckedKeys([]);
    valueMenu.value = [];
    isFormShow.value = true;
};

// 8. 打开编辑弹窗（核心：回显角色信息和菜单选中状态）
const openEditForm = async (row: any) => {
    isEditMode.value = true;
    currentEditId.value = row.id; // 记录当前编辑的角色ID

    // 回显角色基础信息
    formData.name = row.name;
    formData.type = row.type.toString(); // 转为字符串，匹配 el-select 的 value 类型

    // 处理菜单 ID 回显：将后端返回的字符串转为数组
    const menusArray = row.menus
        ? row.menus.split(",").map((id: string) => parseInt(id.trim(), 10))
        : [];
    valueMenu.value = menusArray; // 同步到提交用的菜单 ID 数组

    // 等待树形菜单数据加载完成后，设置选中状态
    await nextTick();
    if (menuTreeRef.value) {
        menuTreeRef.value.setCheckedKeys(menusArray);
    }

    isFormShow.value = true; // 显示弹窗
};
// 9. 关闭弹窗：重置状态
const closeForm = () => {
    isFormShow.value = false;
    if (formRef.value) formRef.value.resetFields();
    if (menuTreeRef.value) menuTreeRef.value.setCheckedKeys([]);
    valueMenu.value = [];
    currentEditId.value = null;
    isEditMode.value = false;
};

// 10. 提交表单（新增/编辑共用）
const submitForm = async () => {
    if (!formRef.value) return;

    await formRef.value.validate(async (valid) => {
        if (valid) {
            // 构造提交参数：编辑时传id，新增时不传
            const requestData: any = {
                name: formData.name,
                type: Number(formData.type), // 转为数字（匹配后端接收类型）
                menus: valueMenu.value.join(',') // 菜单ID数组转字符串（如"1,2,3"）
            };
            // 编辑模式：添加角色ID
            if (isEditMode.value && currentEditId.value) {
                requestData.id = currentEditId.value;
            }

            try {
                // 调用共用接口roleAdd
                const response = await roleAdd(requestData);
                if (response.code === 1) {
                    fetchFullData(); // 重新加载角色列表
                    closeForm(); // 关闭弹窗
                    ElMessage.success(requestData.id ? '编辑角色成功' : '新增角色成功');
                    console.log(isEditMode.value, currentEditId.value);

                } else {
                    ElMessage.error(requestData.id ? '编辑角色失败' : '新增角色失败');
                }
            } catch (err) {
                console.error('提交角色数据失败', err);
                ElMessage.error('提交失败，请检查网络或接口配置');
            }
        }
    });
};

// ---------------------- 删除功能 ----------------------
const open = (row: any) => {
    ElMessageBox.confirm(
        '确定要删除该角色吗？删除后不可恢复！',
        '删除确认',
        {
            confirmButtonText: '确认',
            cancelButtonText: '取消',
            type: 'warning',
        }
    )
        .then(async () => {
            try {
                const res = await roleDelete({ id: row.id });
                if (res.code === 1) {
                    ElMessage({ type: 'success', message: '删除成功' });
                    fetchFullData(); // 重新加载列表
                } else {
                    ElMessage.error('删除失败：' + (res.message || '未知错误'));
                }
            } catch (err) {
                console.error('删除角色失败', err);
                ElMessage.error('删除失败，请重试');
            }
        })
        .catch(() => {
            ElMessage({ type: 'info', message: '已取消删除' });
        });
};
</script>

<style scoped>
.menu-management {
    padding: 20px;
}

.box {
    padding-left: 10px;
}

.size-24 {
    font-size: 24px;
    font-weight: 600;
    color: #1f2937;
    margin-bottom: 20px;
}

.search-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}

.flex {
    display: flex;
}

.gap-4 {
    gap: 16px;
}

.items-center {
    align-items: center;
}

/* 分页 */
.demo-pagination-block {
    margin-top: 20px;
    display: flex;
    justify-content: center;
}

.el-button--small {
    --el-button-size: 35px;
    height: var(--el-button-size);
}
</style>